home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Graphics Samples / ShapePart Browser ƒ / ShapeAction.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-15  |  8.0 KB  |  335 lines  |  [TEXT/KAHL]

  1. /*
  2.  *    ShapeAction.c
  3.  *
  4.  *    Robert Dierkes,  April 26, 1993
  5.  */
  6.  
  7. #include "graphics routines.h"
  8. #include "graphics libraries.h"
  9. #include "qd library.h"            /* ShortRectToFixed for DrawGrayBox */
  10.  
  11. #include "ResourceIDs.h"
  12. #include "ShapeAction.h"
  13. #include "ShapeSetup.h"
  14.  
  15.  
  16. /*----------------------*/
  17. /*    Global Declarations    */
  18. /*----------------------*/
  19.  
  20.  
  21. /*------------------------------*/
  22. /*    External Declarations     */
  23. /*------------------------------*/
  24. extern    GlobalStructure    globals;
  25.  
  26.  
  27. /*------------------------------*/
  28. /*       Local ProtoTypes       */
  29. /*------------------------------*/
  30. void ShowLocalBounds (gxShape *p1stShape, long shapeCount);
  31. void HighlightShapePartBoxes (ControlHandle *ph1stControl, gxShapePart partsHit);
  32. long GetShapeBoxIndexFromPoint (gxShape boxes, gxPoint *pWhere);
  33. void UpdateShapeName (gxShape theShape, gxShapeType *pLastType);
  34. pascal void DrawGrayBox (WindowPtr pWindow, short itemNum);
  35.  
  36.  
  37.     void
  38. ShowLocalBounds (gxShape *p1stShape, long shapeCount)
  39. {
  40.     register
  41.     gxShape        *pShape,
  42.                 rectShape;
  43.     gxRectangle    bounds;
  44.  
  45.     pShape = p1stShape + shapeCount - 1;
  46.  
  47.     rectShape = GXNewShape (gxRectangleType);
  48.     GXSetShapeFill (rectShape, gxClosedFrameFill);
  49.     SetShapeCommonColor (rectShape, gxGray);
  50.  
  51.     while (shapeCount--)
  52.     {
  53.         GXGetShapeLocalBounds (*pShape--, &bounds);
  54.         GXSetRectangle (rectShape, &bounds);
  55.         GXDrawShape (rectShape);
  56.     }
  57.  
  58.     GXDisposeShape (rectShape);
  59. }
  60.  
  61.  
  62.     void
  63. ShowControlPoints (gxShape *p1stShape, long shapeCount)
  64. {
  65.     register
  66.     gxShape        *pShape;
  67.     long        contourCount,
  68.                 pointCount;
  69.     gxPoint        pt;
  70.     gxShape        pointShape;
  71.     gxRectangle    bounds;
  72.  
  73.     pShape = p1stShape + shapeCount - 1;
  74.     pointShape = GXNewShape (gxRectangleType);
  75.  
  76.     while (shapeCount--)
  77.     {
  78.         /* gxGlyphType has too many control gxPoint so skip it */
  79.         if (GXGetShapeType (*pShape) != gxGlyphType)
  80.         {
  81.             contourCount = GXCountShapeContours (*pShape);
  82.             while (contourCount--)
  83.             {
  84.                 pointCount = GXGetShapePoints (*pShape, 1, gxSelectToEnd, nil);
  85.                 while (pointCount)
  86.                 {
  87.                     GetShapeIndexPoint (*pShape, pointCount--, &pt);
  88.                     bounds.left   = pt.x - fixed1;
  89.                     bounds.top    = pt.y - fixed1;
  90.                     bounds.right  = pt.x + fixed1;
  91.                     bounds.bottom = pt.y + fixed1;
  92.                     GXSetRectangle (pointShape, &bounds);
  93.                     GXDrawShape (pointShape);
  94.                 }
  95.             }
  96.         }
  97.         pShape--;
  98.     }
  99.  
  100.     GXDisposeShape (pointShape);
  101. }
  102.  
  103.  
  104. /*
  105.  *
  106.  */
  107.      void
  108. HighlightShapePartBoxes (ControlHandle *ph1stControl, gxShapePart partsHit)
  109. {
  110.     #define    controlCount    11
  111.  
  112.     ControlHandle    *pControl;
  113.     gxRectangle        controlRect;
  114.     gxShape            highlight;
  115.     static
  116.     gxShapePart        lastPartsHit = gxAnyPart;
  117.     gxShapePart        partMask;
  118.  
  119.     if (partsHit == lastPartsHit)
  120.         return;
  121.  
  122.     highlight = GXNewShape (gxRectangleType);
  123.     GXSetShapeFill (highlight, gxClosedFrameFill);
  124.     GXIgnoreGraphicsNotice (color_already_set);
  125.  
  126.     partMask = gxPatternPart;
  127.     for (pControl = ph1stControl + controlCount; --pControl >= ph1stControl; partMask >>= 1)
  128.     {
  129.         /* Compare single bit of current gxShapeParts against previous gxShapeParts */
  130.         if ((partsHit & partMask) != (lastPartsHit & partMask))
  131.         {
  132.             (void) ShortRectToFixed (&(**pControl)->contrlRect, &controlRect);
  133.             controlRect.left   -= fixed1;
  134.             controlRect.top    -= fixed1;
  135.             controlRect.right  += fixed1;
  136.  
  137.             GXSetRectangle (highlight, &controlRect);
  138.             SetShapeCommonColor (highlight, (partsHit & partMask) ? red : gxWhite);
  139.             GXDrawShape (highlight);
  140.         }
  141.     }
  142.     lastPartsHit = partsHit;
  143.  
  144.     GXPopGraphicsNotice ();
  145.     GXDisposeShape (highlight);
  146. }
  147.  
  148.  
  149.     pascal void
  150. DrawGrayBox (WindowPtr pWindow, short itemNum)
  151. {
  152.     GrafPtr        savedPort;
  153.     Rect        shortBounds;
  154.     gxRectangle    bounds;
  155.     gxShape        boxShape;
  156.  
  157.     GetPort (&savedPort);
  158.     SetPort (pWindow);
  159.  
  160.     GetDItem (pWindow, itemNum, nil, nil, &shortBounds);
  161.     ShortRectToFixed (&shortBounds, &bounds);
  162.     boxShape = GXNewRectangle (&bounds);
  163.     GXSetShapeFill (boxShape, gxClosedFrameFill);
  164.     GXSetShapePen (boxShape, 4 * fixed1);
  165.     SetShapeCommonColor (boxShape, grayish + silver);
  166.     GXDrawShape (boxShape);
  167.     GXDisposeShape (boxShape);
  168.  
  169.     SetPort (savedPort);
  170.  
  171. }
  172.  
  173.  
  174.     void
  175. UpdateHitTestWindow (WindowPtr pWindow)
  176. {
  177.     register
  178.     gxShape        *pShape;
  179.     long        shapeCount,
  180.                 shapeCountDown;
  181.  
  182.     UpdtDialog (pWindow, pWindow->visRgn);
  183.  
  184.     DrawGrayBox (pWindow, userGrayShapeNameBox);
  185.     DrawGrayBox (pWindow, userGrayShapePartsBox);
  186.     HighlightShapePartBoxes (&globals.hBounds, globals.partsHit);
  187.  
  188.     shapeCount = shapeCountDown = GXCountShapeContours (globals.boxes);
  189.  
  190.     /* Draw the background boxes */
  191.     GXDrawShape (globals.boxes);
  192.  
  193.     if (globals.showLocalBounds)
  194.         ShowLocalBounds (globals.pShapes, shapeCount);
  195.  
  196.     /* Draw all the hit testing shapes */
  197.     pShape = globals.pShapes;
  198.     while (shapeCountDown--)
  199.         GXDrawShape (*pShape++);
  200.  
  201.     if (globals.showControlPoints)
  202.         ShowControlPoints (globals.pShapes, shapeCount);
  203. }
  204.  
  205.  
  206.     long
  207. GetShapeBoxIndexFromPoint (gxShape boxes, gxPoint *pWhere)
  208. {
  209.     gxRectangle    bounds;
  210.     long        index;
  211.  
  212.     index = GXCountShapeContours (boxes);
  213.     while (index)
  214.     {
  215.         GXGetShapeBounds (boxes, index, &bounds);
  216.         if (GXTouchesRectanglePoint (&bounds, pWhere))
  217.             return (index - 1);
  218.         index--;
  219.     }
  220.     return (notOnAnyShape);
  221. }
  222.  
  223.  
  224.     void
  225. UpdateShapeName (gxShape theShape, gxShapeType *pLastType)
  226. {
  227.     gxShapeType    newType;
  228.     Handle        itemHandle;
  229.     Str255        shapeNames[] = {"\pPoint",
  230.                                 "\pLine",
  231.                                 "\pCurve",
  232.                                 "\pRectangle",
  233.                                 "\pPolygon",
  234.                                 "\pPath",
  235.                                 "\pBitmap",
  236.                                 "\pText",
  237.                                 "\pGlyph",
  238.                                 "\p"
  239.                                 };
  240.     StringPtr    pShapeName;
  241.  
  242.     if (theShape == nil)
  243.         newType = gxEmptyType;
  244.     else if ((newType = GXGetShapeType (theShape)) == *pLastType)
  245.         return;
  246.  
  247.     *pLastType = newType;
  248.  
  249.     switch (newType)
  250.     {
  251.         case gxPointType:        pShapeName = shapeNames [0];    break;
  252.         case gxLineType:        pShapeName = shapeNames [1];    break;
  253.         case gxCurveType:        pShapeName = shapeNames [2];    break;
  254.         case gxRectangleType:    pShapeName = shapeNames [3];    break;
  255.         case gxPolygonType:    pShapeName = shapeNames [4];    break;
  256.         case gxPathType:        pShapeName = shapeNames [5];    break;
  257.         case gxBitmapType:    pShapeName = shapeNames [6];    break;
  258.         case gxTextType:        pShapeName = shapeNames [7];    break;
  259.         case gxGlyphType:        pShapeName = shapeNames [8];    break;
  260.         default:            pShapeName = shapeNames [9];    break;
  261.     }
  262.  
  263.     GetDItem (thePort, staticShapeName, nil, &itemHandle, nil);
  264.     SetIText (itemHandle, pShapeName);
  265. }
  266.  
  267.  
  268. /*
  269.     Draws a red gxRectangle around check box if the given gxPoint hit that type of gxShape part.
  270. */
  271.     void
  272. UpdateShapePartInfo (Point *pQDWhere, GlobalStructure *pG)
  273. {
  274.     gxPoint        where;
  275.     gxHitTestInfo    hitInfo;
  276.     long        boxIndex;
  277.     static
  278.     gxShapeType    lastType = gxEmptyType;
  279.     gxShape        shapeHit;
  280.  
  281.     ShortPointToFixed (pQDWhere, &where);
  282.     boxIndex = GetShapeBoxIndexFromPoint (pG->boxes, &where);
  283.  
  284.     /* Change checkbox titles if gxPoint is in glyph gxShape */
  285.     if (boxIndex == kWordGlyphs  &&  lastType != gxGlyphType)
  286.     {
  287.         Point    joinSize     = {16, 106},
  288.                 startCapSize = {16, 90},
  289.                 endCapSize     = {16, 88},
  290.                 dashSize     = {16, 100};
  291.  
  292.         SizeControl (pG->hJoin, joinSize.h, joinSize.v);
  293.         SizeControl (pG->hStartCap, startCapSize.h, startCapSize.v);
  294.         SizeControl (pG->hEndCap, endCapSize.h, endCapSize.v);
  295.         SizeControl (pG->hDash, dashSize.h, dashSize.v);
  296.         SetCTitle (pG->hJoin,      "\pGlyph Bounds");
  297.         SetCTitle (pG->hStartCap, "\pGlyph First");
  298.         SetCTitle (pG->hEndCap,   "\pGlyph Last");
  299.         SetCTitle (pG->hDash,      "\pSide Bearing");
  300.     }
  301.     else if (boxIndex != kWordGlyphs  &&  lastType == gxGlyphType)
  302.     {
  303.         Point    joinSize     = {16, 48},
  304.                 startCapSize = {16, 82},
  305.                 endCapSize     = {16, 72},
  306.                 dashSize     = {16, 52};
  307.         Rect    invalid         = {274, 528, 354, 588};
  308.  
  309.         InvalRect (&invalid);
  310.         SizeControl (pG->hJoin, joinSize.h, joinSize.v);
  311.         SizeControl (pG->hStartCap, startCapSize.h, startCapSize.v);
  312.         SizeControl (pG->hEndCap, endCapSize.h, endCapSize.v);
  313.         SizeControl (pG->hDash, dashSize.h, dashSize.v);
  314.         SetCTitle (pG->hJoin,      "\pJoin");
  315.         SetCTitle (pG->hStartCap, "\pStart Cap");
  316.         SetCTitle (pG->hEndCap,      "\pEnd Cap");
  317.         SetCTitle (pG->hDash,      "\pDash");
  318.     }
  319.  
  320.     if (boxIndex == notOnAnyShape)
  321.     {
  322.         shapeHit = nil;
  323.         hitInfo.what = gxNoPart;
  324.     }
  325.     else
  326.     {
  327.         shapeHit = pG->pShapes [boxIndex];
  328.         GXHitTestShape (pG->pShapes [boxIndex], &where, &hitInfo);
  329.     }
  330.  
  331.     UpdateShapeName (shapeHit, &lastType);
  332.     HighlightShapePartBoxes (&pG->hBounds, hitInfo.what);
  333.     pG->partsHit = hitInfo.what;
  334. }
  335.